home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 January: Mac OS SDK / Dev.CD Jan 96 SDK / Dev.CD Jan 96 SDK1.toast / Development Kits (Disc 1) / AppleScript / Development Tools / Sample Code / 7Edit / C Sources / SVEditUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-25  |  16.5 KB  |  621 lines  |  [TEXT/MPS ]

  1. /*
  2.     SVEditUtils.c
  3.     
  4.     Version 3.0d9
  5.     
  6.     Copyright © SRL Data 1992, 1993
  7.     
  8.     All rights reserved
  9.     
  10.     Produced by : SRL Data
  11.     Originally Developed for UK.DTS
  12. */
  13.  
  14.  
  15. /*
  16.     Changes for 3.0d4:
  17.         
  18.         5-Aug-92    : NH : Modified styles to use TEContinuousStyle like IM IV
  19.     
  20.     Changes for 3.0d6:
  21.         
  22.         9-Sep-92    : JL : Changed FeatureIsImplemented to use BitTst
  23.                          Added setting of gRecordingIsImplemented flag
  24. */
  25.  
  26. #include <PLStringFuncs.h>
  27. #include <Events.h>
  28. #include <Traps.h>
  29. #include <Dialogs.h>
  30. #include <Fonts.h>
  31. #include <Packages.h>
  32. #include <ToolUtils.h>
  33. #include <AppleEvents.h>
  34. #include "SVEditUtils.h"
  35.  
  36. /**-----------------------------------------------------------------------
  37.         Name:             LesserOf
  38.         Purpose:        Returns the Lesser of two longints.
  39.     -----------------------------------------------------------------------**/
  40. #pragma segment Utils
  41.         
  42. pascal long LesserOf(long A, long B)
  43.  {
  44.    if (A<B)
  45.        return(A);
  46.      else
  47.        return(B);
  48.  }   /*LesserOf*/
  49.             
  50. /**-----------------------------------------------------------------------
  51.         Name:             GreaterOf
  52.         Purpose:        Returns the Greater of two longints.
  53.     -----------------------------------------------------------------------**/
  54.     
  55. #pragma segment Utils
  56.         
  57. pascal long GreaterOf(long A, long B)
  58.  {
  59.    if (A>B)
  60.        return(A);
  61.      else
  62.        return(B);
  63.  }  /*GreaterOf*/
  64.             
  65. /**-----------------------------------------------------------------------
  66.         Name:             ShowError
  67.         Purpose:        Reports an error to the user as both string and number.
  68.     -----------------------------------------------------------------------**/
  69. #pragma segment Utils
  70.         
  71. pascal void ShowError(Str255  theError,
  72.                                           long    theErrorCode)
  73. {
  74.    short     alertResult;
  75.    Str255    theString;
  76.      OSErr     myErr;
  77.      
  78.      myErr = AEInteractWithUser(kAEDefaultTimeout, nil,nil);
  79.      
  80.      if (myErr == noErr)
  81.        {
  82.              SetCursor(&qd.arrow);
  83.              NumToString(theErrorCode, theString);
  84.              ParamText(theError, theString, (unsigned char *)"", (unsigned char *)"");
  85.              alertResult = Alert(300, nil);
  86.          }
  87. } /* ShowError */
  88.  
  89. /**-----------------------------------------------------------------------
  90.         Name:             Ours
  91.         Purpose:        Checks the frontmost window belongs to the app.
  92.     -----------------------------------------------------------------------**/
  93. #pragma segment Utils        
  94.     
  95. pascal Boolean Ours(WindowPtr aWindow)
  96.  {
  97.         if (aWindow)
  98.             if (((WindowPeek)aWindow)->windowKind == zoomDocProc)
  99.                 return(true);
  100.         return(false);
  101. } /* Ours */
  102.  
  103. /**-----------------------------------------------------------------------
  104.         Name:             SetShortMenus
  105.         Purpose:        Cuts the menus down to a minimum - Apple File Edit.
  106.                                 Greys out the unavailable options - used when no docs open
  107.     -----------------------------------------------------------------------**/
  108. #pragma segment Utils        
  109.  
  110. pascal void SetShortMenus()
  111.     DeleteMenu(mfontID);
  112.     DeleteMenu(sizeID);
  113.     DeleteMenu(styleID);
  114.  
  115.     DisableItem(myMenus[fileM], fmClose);
  116.     DisableItem(myMenus[fileM], fmSave);
  117.     DisableItem(myMenus[fileM], fmSaveAs);
  118.     DisableItem(myMenus[fileM], fmRevert);
  119.     DisableItem(myMenus[fileM], fmPrint);
  120.     DisableItem(myMenus[fileM], fmPageSetUp);
  121.  
  122.     /* now the unnecessary items on the edit menu */
  123.                 
  124.     DisableItem(myMenus[editM], undoCommand);
  125.     DisableItem(myMenus[editM], cutCommand);
  126.     DisableItem(myMenus[editM], copyCommand);
  127.     DisableItem(myMenus[editM], clearCommand);
  128.     DisableItem(myMenus[editM], pasteCommand);
  129.     DisableItem(myMenus[editM], selectAllCommand);
  130.  
  131.     DrawMenuBar();
  132. }  /* SetShortMenus */
  133.  
  134. /**-----------------------------------------------------------------------
  135.         Name:             SetLongMenus
  136.         Purpose:        Reinstates the full menu bar - called when first document
  137.                     opened.
  138.     -----------------------------------------------------------------------**/
  139. #pragma segment Utils        
  140.  
  141. pascal void SetLongMenus()
  142.   {
  143.         InsertMenu(myMenus[fontM], 0);
  144.         InsertMenu(myMenus[sizeM], 0);
  145.         InsertMenu(myMenus[styleM], 0);
  146.  
  147.         EnableItem(myMenus[fileM], fmClose);
  148.         EnableItem(myMenus[fileM], fmSave);
  149.         EnableItem(myMenus[fileM], fmSaveAs);
  150.         EnableItem(myMenus[fileM], fmRevert);
  151.         EnableItem(myMenus[fileM], fmPrint);
  152.         EnableItem(myMenus[fileM], fmPageSetUp);
  153.  
  154.         /* now the necessary items on the edit menu -
  155.             many other items fixed on each pass thru the main event
  156.             loop or before the window pulled down
  157.         */
  158.         
  159.         EnableItem(myMenus[editM], selectAllCommand);
  160.  
  161.         DrawMenuBar();
  162.     }  /* SetLongMenus */
  163.  
  164. /**-----------------------------------------------------------------------
  165.         Name:             SetStyleMenu
  166.         Purpose:        Sets the style menu checking to reflect the style of the
  167.                     first character of the current selection in the given
  168.                                 document.
  169.     -----------------------------------------------------------------------**/
  170. #pragma segment Utils        
  171.         
  172. pascal void SetStyleMenu(DPtr theDoc)
  173.   {
  174.     TextStyle        theTStyle;
  175.         short       contMode;
  176.         short       i;
  177.         
  178.         contMode = doFace;
  179.         
  180.         TEContinuousStyle(&contMode,&theTStyle,theDoc->theText);
  181.         
  182.         if ((contMode & doFace) != 0)
  183.             {
  184.                 CheckItem(myMenus[styleM], cPlain,     (theTStyle.tsFace == 0));
  185.                 CheckItem(myMenus[styleM], cBold,      (bold      & theTStyle.tsFace));
  186.                 CheckItem(myMenus[styleM], cItalic,    (italic    & theTStyle.tsFace));
  187.                 CheckItem(myMenus[styleM], cUnderline, (underline & theTStyle.tsFace));
  188.                 CheckItem(myMenus[styleM], cOutline,   (outline   & theTStyle.tsFace));
  189.                 CheckItem(myMenus[styleM], cShadow,    (shadow    & theTStyle.tsFace));
  190.                 CheckItem(myMenus[styleM], cCondense,  (condense  & theTStyle.tsFace));
  191.                 CheckItem(myMenus[styleM], cExtend,    (extend    & theTStyle.tsFace));
  192.           }
  193.         else
  194.             for (i=cPlain; i<= cExtend; i++)
  195.                 CheckItem(myMenus[styleM], i,     false);
  196.   }
  197.  
  198. /**-----------------------------------------------------------------------
  199.     Name:       SetSizeMenu
  200.     Purpose:    Outline all the items if the current font is an
  201.                 outline font. Check the size of the current selection
  202.   -----------------------------------------------------------------------**/
  203. #pragma segment Utils        
  204.  
  205. pascal void SetSizeMenu(DPtr theDoc)
  206.   {
  207.       short             i;
  208.         short                aSize;
  209.         short                max;
  210.     long                 theSize;
  211.     Str255        name;
  212.     Boolean       sizeinMenu;
  213.     Boolean       oldState;
  214.     Point         numer;
  215.     TextStyle        theStyle;
  216.         TEHandle    myText;
  217.         short       contMode;
  218.       
  219.     numer.h = 1;
  220.     numer.v = 1;
  221.  
  222.     myText = theDoc->theText;
  223.         
  224.         contMode = doSize+doFont;
  225.         
  226.         TEContinuousStyle(&contMode,&theStyle,theDoc->theText);
  227.         
  228.     sizeinMenu = false;
  229.     max = CountMItems(myMenus[sizeM]);
  230.         for (i = 1; i <= max - 5; i++)
  231.       {
  232.                 GetItem(myMenus[sizeM], i, name);
  233.                 StringToNum(name, &theSize);
  234.                 aSize = (short)theSize;
  235.  
  236.                 if (RealFont(theStyle.tsFont, aSize) && (contMode & doFont) != 0) // there is only one font and this size exists
  237.                     SetItemStyle(myMenus[sizeM], i, outline);
  238.                 else
  239.                     SetItemStyle(myMenus[sizeM], i, 0);
  240.  
  241.                 if ((aSize == theStyle.tsSize) && (contMode & doSize) != 0)
  242.                     {
  243.                         sizeinMenu = true;
  244.                         CheckItem(myMenus[sizeM], i, true);
  245.                     }
  246.                 else
  247.                     CheckItem(myMenus[sizeM], i, false);
  248.             }
  249.         
  250.             /*
  251.                 if it's not a size in the menu,and there is only one size in the
  252.               selection range check the other item
  253.             */
  254.             
  255.             if (!sizeinMenu && (contMode & doSize) != 0)
  256.               CheckItem(myMenus[sizeM], max, true);
  257.             else
  258.                 CheckItem(myMenus[sizeM], max, false);
  259.  
  260.             /*if this is an outline font, set the rest of the items to outline style*/
  261.             /*RealFont will ensure that the sizes are outlined*/
  262.  
  263.             oldState = GetOutlinePreferred();
  264.             SetOutlinePreferred(true);
  265.             for (i = max-4; i <= max; i++)
  266.                 {
  267.                     if (IsOutline(numer, numer) && (contMode & doFont)!= 0)
  268.                         SetItemStyle(myMenus[sizeM], i, outline);
  269.                     else
  270.                         SetItemStyle(myMenus[sizeM], i, 0);
  271.                 }
  272.                 
  273.             SetOutlinePreferred(oldState);
  274.     }
  275.  
  276. /**-----------------------------------------------------------------------
  277.     Name:       SetEditMenu
  278.     Purpose:    Set the text of the edit menu according to the state of
  279.                                 current document.
  280.   -----------------------------------------------------------------------**/
  281.  
  282. #pragma segment Utils
  283.  
  284. pascal void SetEditMenu(DPtr theDoc)
  285.     {
  286.         if (theDoc->showBorders)
  287.             SetItem(myMenus[editM], cBorders, (unsigned char *)"\pHide Borders");
  288.         else
  289.             SetItem(myMenus[editM], cBorders, (unsigned char *)"\pShow Borders");
  290.     }  /* SetEditMenu */
  291.             
  292. /**-----------------------------------------------------------------------
  293.     Name:       SetFontMenu
  294.     Purpose:    Set the font menu according to the state of
  295.                                 current selection of the supplied document.
  296.   -----------------------------------------------------------------------**/
  297. #pragma segment Utils
  298.         
  299. pascal void SetFontMenu(DPtr theDoc)
  300.   {
  301.     MenuHandle        theMHandle;
  302.     short         theNumber;
  303.     short         i;
  304.     short                max;
  305.     Str255        name;
  306.     TextStyle     theStyle;
  307.         short         contMode;
  308.  
  309.         theMHandle = GetMHandle(mfontID);
  310.  
  311.         if (gFontMItem)
  312.       CheckItem(theMHandle, gFontMItem, false);
  313.             
  314.         max = CountMItems(theMHandle);
  315.  
  316.         contMode = doFont;
  317.         TEContinuousStyle(&contMode,&theStyle,theDoc->theText);
  318.  
  319.         gFontMItem = 0;
  320.         
  321.     if (contMode & doFont)
  322.             for (i=1; i<=max; i++)
  323.                 {
  324.                     GetItem(theMHandle, i, name);
  325.                     GetFNum(name, &theNumber);
  326.                     if (theNumber == theStyle.tsFont)
  327.                         gFontMItem = i;
  328.                 }
  329.  
  330.     if (gFontMItem)
  331.       CheckItem(theMHandle, gFontMItem, true);
  332.             
  333.         SetSizeMenu(theDoc);
  334.         SetStyleMenu(theDoc);
  335.     }
  336.  
  337. /**-----------------------------------------------------------------------
  338.     Name:       GetTempFileName
  339.     Purpose:    Fills newstring with a temporary file name.
  340.   -----------------------------------------------------------------------**/
  341.  
  342. #pragma segment Utils
  343.  
  344. pascal void GetTempFileName(DPtr aDoc,
  345.                             Str255 newString)
  346.  
  347.     {
  348.        Str255        s;
  349.      Str255        fileName;
  350.  
  351.         if (aDoc->everSaved == false)
  352.           PLstrcpy(fileName, (unsigned char *)"\pTEXTra");
  353.         else
  354.             PLstrcpy(fileName, aDoc->theFileName);
  355.  
  356.     /*generate a unique(ish) temporary filename*/
  357.         
  358.         if (fileName[0] > 21)
  359.           fileName[0] = 21;
  360.                 
  361.         NumToString(TickCount(), s);
  362.         
  363.         PLstrcat(fileName, s);
  364.         
  365.         PLstrcpy(newString,fileName);
  366.     }
  367.  
  368. /**-----------------------------------------------------------------------
  369.     Name:       SetText
  370.     Purpose:    Sets the text of the supplied itemNo in aDialog to 
  371.                                 theString and select it.
  372.   -----------------------------------------------------------------------**/
  373.  
  374. #pragma segment Utils
  375.  
  376. pascal void SetText(DialogPtr aDialog,
  377.                     short     itemNo,
  378.                     Str255    theString)
  379.   {
  380.     Handle      itemHandle;
  381.     Rect        box;
  382.     short       kind;
  383.     TEHandle    theTEHandle;
  384.  
  385.         GetDItem(aDialog, itemNo, &kind, &itemHandle, &box);
  386.         SetIText(itemHandle, theString);
  387.         
  388.         theTEHandle = ((DialogPeek)aDialog)->textH;
  389.  
  390.         /*set all the text to be selected*/
  391.         if (theTEHandle)
  392.             TESetSelect(0, 255, theTEHandle);
  393.     }
  394.             
  395. /**-----------------------------------------------------------------------
  396.     Name:       RetrieveText
  397.     Purpose:    Returns the text of anItem in aDialog in aString.
  398.   -----------------------------------------------------------------------**/
  399.  
  400. #pragma segment Utils
  401.  
  402. pascal void RetrieveText(DialogPtr aDialog,
  403.                                                short     anItem,
  404.                                                Str255    aString)
  405.   {
  406.      short      kind;
  407.      Rect       box;
  408.      Handle     itemHandle;
  409.  
  410.          GetDItem(aDialog, anItem, &kind, &itemHandle, &box);
  411.          GetIText(itemHandle, aString);
  412.   }
  413.  
  414. /**-----------------------------------------------------------------------
  415.     Name:       DrawDefaultOutline
  416.     Purpose:    Draws an outline around theItem.
  417.                                 Called as a useritem Proc by the dialog manager.
  418.                                 To use place a useritem over the default item in the
  419.                                 dialog and install the address of this proc as the item
  420.                                 handle.
  421.   -----------------------------------------------------------------------**/
  422.  
  423. #pragma segment Utils
  424.  
  425. pascal void DrawDefaultOutline(DialogPtr theDialog, short theItem)
  426.   {
  427.       short       kind;
  428.     Handle      itemHandle;
  429.     Rect        box;
  430.                 
  431.     GetDItem(theDialog, theItem, &kind, &itemHandle, &box);
  432.     PenSize(3, 3);
  433.     InsetRect(&box, - 4, - 4);
  434.     FrameRoundRect(&box, 16, 16);
  435.     PenNormal();
  436.         
  437.     }  /* DrawDefaultOutline */
  438.             
  439. /**-----------------------------------------------------------------------
  440.     Name:       AdornDefaultButton
  441.     Purpose:    Installs DrawDefaultOutline as the useritem proc
  442.                     for the given item.
  443.   -----------------------------------------------------------------------**/
  444.  
  445. #pragma segment Utils
  446.         
  447. pascal void AdornDefaultButton(DialogPtr theDialog,short theItem)
  448.   {
  449.       short       kind;
  450.     Handle      itemHandle;
  451.     Rect        box;
  452.  
  453.         GetDItem(theDialog, theItem, &kind, &itemHandle, &box);
  454.         SetDItem(theDialog, theItem, kind, (Handle)&DrawDefaultOutline, &box);
  455.   }
  456.  
  457.     /*-------  Determining of Gestalt is available ---------------*/
  458.     /*The following routines come from the Inside Mac VI recommendations*/
  459.     /*about how to find if a trap is available*/
  460.          /*
  461.             The glue for Gestalt will be in MPW 3.2, so if it is available we will also
  462.              need to check the system version
  463.         */
  464.  
  465. pascal void GetRectOfDialogItem(DialogPtr theDialog, short theItem, Rect *theRect)
  466.     {
  467.       short       kind;
  468.     Handle      itemHandle;
  469.         
  470.         GetDItem(theDialog, theItem, &kind, &itemHandle, theRect);
  471.     }
  472.  
  473. #pragma segment Utils
  474.  
  475. pascal short NumToolboxTraps()
  476.   {
  477.         if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
  478.             return(0x200);
  479.         else
  480.             return(0x400);
  481.     }
  482.  
  483. #pragma segment Utils
  484.  
  485. #define TrapMask  0x0800
  486.  
  487. pascal TrapType GetTrapType(short theTrap)
  488.   {
  489.         if ((theTrap & TrapMask) > 0)
  490.             return(ToolTrap);
  491.         else
  492.             return(OSTrap);
  493.     }
  494.  
  495. #pragma segment Utils
  496.  
  497. pascal Boolean TrapAvailable(short theTrap)
  498.   {
  499.         TrapType  tType;
  500.  
  501.         tType = GetTrapType(theTrap);
  502.         if (tType == ToolTrap)
  503.             {
  504.                 theTrap = theTrap & 0x07FF;
  505.                 if (theTrap >= NumToolboxTraps())
  506.                     theTrap = _Unimplemented;
  507.             }
  508.         return(NGetTrapAddress(theTrap, tType) != NGetTrapAddress(_Unimplemented,ToolTrap));
  509.     }
  510.  
  511. #pragma segment Utils
  512.  
  513. #define _Gestalt 0xA1AD
  514.  
  515. pascal Boolean GestaltAvailable()
  516.   {
  517.         return(TrapAvailable(_Gestalt));
  518.     }
  519.  
  520. /**------  FeatureIsImplemented    ------------**/
  521. /*This is called to use Gestalt to determine if a feature is implemented.
  522.  This applies to only those referenced by OSType*/
  523.  
  524. #pragma segment Utils
  525.  
  526. pascal Boolean FeatureIsImplemented(OSType  theFeature,
  527.                                                           short   theTestBit)
  528.   {
  529.     OSErr     err;
  530.     long      result;
  531.  
  532.         err = Gestalt(theFeature, &result);
  533.         if (err == noErr)
  534.             if (BitTst(&result, 31 -theTestBit))
  535.                 return(true);
  536.       return(false);
  537.     }
  538.  
  539. #pragma segment Utils
  540.  
  541. pascal Boolean CheckEnvironment()
  542.   {
  543.         /*
  544.          first determine of Gestalt is available- if it isn't exit
  545.          as we only run under 7.0.  It could it present in 6.04 - so we need
  546.          to do some further checks for important features
  547.         */
  548.  
  549.         gGestaltAvailable = GestaltAvailable();
  550.         
  551.         if (!gGestaltAvailable)
  552.             return(false);
  553.  
  554.     /*first check if the Edition Manager is present*/
  555.                 
  556.     gEditionManagerImplemented = FeatureIsImplemented(gestaltEditionMgrAttr,
  557.                                                                                                           gestaltEditionMgrPresent);
  558.  
  559.         /*and for good measure- the Alias manager*/
  560.                 
  561.         gAliasManagerImplemented  = FeatureIsImplemented(gestaltAliasMgrAttr,
  562.                                                                                                          gestaltAliasMgrPresent);
  563.             
  564.         /*check for the AppleEvents manager - we certainly can't work without it*/
  565.         
  566.         gAppleEventsImplemented   = FeatureIsImplemented(gestaltAppleEventsAttr,
  567.                                                                                                          gestaltAppleEventsPresent);
  568.         
  569.         /*check if recording is implemented*/
  570.         
  571.         gRecordingImplemented   = FeatureIsImplemented(gestaltAppleEventsAttr,1);
  572.             
  573.         /*check for the Outline fonts*/
  574.         
  575.         gOutlineFontsImplemented  = FeatureIsImplemented(gestaltFontMgrAttr,
  576.                                                                                                          gestaltOutlineFonts);
  577.         
  578.         return (gEditionManagerImplemented &&
  579.                         gAliasManagerImplemented   &&
  580.                         gAppleEventsImplemented    &&
  581.                         gOutlineFontsImplemented);
  582.                                 
  583.     }  /* CheckEnvironment */
  584.             
  585.     /*
  586.         DoPageSetup returns true if the page setup of the document is altered
  587.     */
  588.     
  589.     pascal Boolean DoPageSetup(DPtr theDoc)
  590.         {
  591.             Boolean result = false;
  592.                 
  593.                 if (theDoc)
  594.                     {
  595.                         PrOpen();
  596.                         result =  PrStlDialog(theDoc->thePrintSetup);
  597.                         PrClose();
  598.                     }
  599.                     
  600.                 return(result);
  601.         }  /* DoPageSetup */
  602.  
  603. /*
  604.     Name:    CtrlKeyPressed
  605.     Purpose: Returns true if control key pressed during event
  606. */
  607. pascal Boolean CtrlKeyPressed(const EventRecord *theEvent)
  608.     {
  609.         return((theEvent->modifiers & controlKey) != 0);
  610.     }
  611.     
  612. /*
  613.     Name:    OptionKeyPressed
  614.     Purpose: Returns true if option key pressed during event
  615. */
  616. pascal Boolean OptionKeyPressed(const EventRecord *theEvent)
  617.     {
  618.         return((theEvent->modifiers & optionKey) != 0);
  619.     }
  620.